#lang racket


(require "../base/main.rkt")
(require "../constructors/main.rkt")

(require "domain.rkt"
         "parametric.rkt")


(provide (struct-out segment)
         
         segment-object
         segment-tangent
         segment-normal
         segment-binormal
         segment-cs)


(define-struct segment
  (parametric domain))


(define (segment-space segment space t-fn)
  (let ((t (t-fn (t-domain-t (segment-domain segment))))
        (parametric (segment-parametric segment)))
     ((space parametric) t)))

(define (segment-object segment (t-fn (t-fn-min)))
  (segment-space segment parametric-object t-fn))

(define (segment-tangent segment (t-fn (t-fn-min)))
  (segment-space segment parametric-tangent t-fn))

(define (segment-normal segment (t-fn (t-fn-min)))
  (segment-space segment parametric-normal t-fn))

(define (segment-binormal segment (t-fn (t-fn-min)))
  (segment-space segment parametric-binormal t-fn))

(define (segment-cs segment node (t-fn (t-fn-min)))
  (define (move-and-rotate)
    (move
     (segment-object segment t-fn)
     (rotate 
      (p<\p 
       ux
       (segment-normal segment t-fn)
       (segment-binormal segment t-fn))
      (segment-binormal segment t-fn)
      node)))
  
  (define (move-no-rotate)
    (move (segment-object segment t-fn) node))
  
  (with-handlers
      ((unsupported? (λ (e) (move-no-rotate))))
    (move-and-rotate)))